
#include <stdlib.h>
#include "rtthread.h"
#include "dev_sign_api.h"
#include "mqtt_api.h"
#include "dfs_file.h"
#include "unistd.h"
#include "fcntl.h"
#include "drivers/pin.h"
#include "cJSON.h"
#include <netdev_ipaddr.h>
#include "netdev.h"

#define AWPARA_KEY_HUMI0ADC         "Humidity0ADCValue"
#define AWPARA_KEY_HUMI100ADC       "Humidity100ADCValue"
#define AWPARA_KEY_INTERVALACTIVE   "IntervalInActive"
#define AWPARA_KEY_INTERVAL         "CheckInterval"
#define AWPARA_KEY_HOLDTIME         "PumpHoldTime"
#define AWPARA_KEY_ACTIVEHUMI       "PumpActiveHumi"
#define AWPARA_KEY_DEACTIVEHUMI     "PumpDeactiveHumi"
#define AWPARA_KEY_CURVOL           "CurrentVoltage"
#define AWPARA_KEY_CURHUMI          "CurrentHumidity"

#ifndef _MIN
#define _MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define MCX_PIN_GET(_port, _pin)    ((_port)<<5|(_pin))
#define PUMP_PIN                    MCX_PIN_GET(0, 14)
#define PUMP_ACTIVE(_pin)           rt_pin_write(_pin, PIN_HIGH)
#define PUMP_NON_ACTIVE(_pin)       rt_pin_write(_pin, PIN_LOW)
#define PUMP_IS_ACTIVE(_pin)        (rt_pin_read(_pin) == PIN_HIGH)

#define AWEVT_HUMI_CHECK    (1 << 0)
#define AWEVT_HUMI_READY    (1 << 1)
#define AWEVT_HUMI_RESTART  (1 << 2)
#define AWEVT_PUMP_STOP     (1 << 3)

#define AWEVT_MAIN_BITS     (AWEVT_HUMI_RESTART|AWEVT_HUMI_READY|AWEVT_PUMP_STOP)

static char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
static char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
static char DEMO_DEVICE_SECRET[IOTX_DEVICE_SECRET_LEN + 1] = {0};

struct awparam
{
    int32_t interval;   // 静默时检测间隔,sec
    int32_t intvwork;   // 工作时检测间隔,sec
    int32_t holdtime;   // 水泵持续时间,sec
    int32_t deact_humi; // 水泵除能湿度
    int32_t act_humi;   // 水泵使能湿度
    int32_t adc0;       // ADC0
    int32_t adc100;     // ADC100
};

static struct awparam _awparam;
static int16_t currentVoltage = -1;
static int pump_active = 0;
/**
 * @brief 检查网络状态
 * 
 * @return int 0=网络不通, 1=网络正常
 */
int _net_stat_check(void)
{
    struct netdev *netdev = RT_NULL;
    netdev = netdev_get_by_name("e0");
    if(netdev == NULL)
    {
        return 0;
    }
    if(netdev_is_internet_up(netdev))
    {
        return 1;
    }
    return 0;
}
/**
 * @brief str to awparam
 * 
 * @param[in] str 
 * @param[out] humi0 
 * @param[out] humi100 
 * @return int 1=parse ok, 0=parse failed.
 */
static int mqtt_property_set_parse(const char *str, struct awparam *para)
{
    cJSON *root = cJSON_Parse(str);
    if(root)
    {
        cJSON *params = cJSON_GetObjectItem(root, "params");
        if(params)
        {
            struct awparam para_tmp;
            cJSON *item;
            para_tmp.adc0       = -1;
            para_tmp.adc100     = -1;
            para_tmp.holdtime   = -1;
            para_tmp.interval   = -1;
            para_tmp.intvwork   = -1;
            para_tmp.act_humi   = -1;
            para_tmp.deact_humi = -1;
            item = cJSON_GetObjectItem(params, AWPARA_KEY_HUMI0ADC);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_HUMI0ADC":%d\r\n", item->valueint);
                    para_tmp.adc0 = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_HUMI0ADC" note found!\r\n");
                }
            }
            item = cJSON_GetObjectItem(params, AWPARA_KEY_HUMI100ADC);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_HUMI100ADC":%d\r\n", item->valueint);
                    para_tmp.adc100 = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_HUMI100ADC" not found!\r\n");
                }
            }
            item = cJSON_GetObjectItem(params, AWPARA_KEY_INTERVALACTIVE);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_INTERVALACTIVE":%d\r\n", item->valueint);
                    para_tmp.intvwork = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_INTERVALACTIVE" not found!\r\n");
                }
            }
            item = cJSON_GetObjectItem(params, AWPARA_KEY_INTERVAL);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_INTERVAL":%d\r\n", item->valueint);
                    para_tmp.interval = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_INTERVAL" not found!\r\n");
                }
            }
            item = cJSON_GetObjectItem(params, AWPARA_KEY_HOLDTIME);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_HOLDTIME":%d\r\n", item->valueint);
                    para_tmp.holdtime = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_HOLDTIME" not found!\r\n");
                }
            }
            item = cJSON_GetObjectItem(params, AWPARA_KEY_ACTIVEHUMI);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_ACTIVEHUMI":%d\r\n", item->valueint);
                    para_tmp.act_humi = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_ACTIVEHUMI" not found!\r\n");
                }
            }
            item = cJSON_GetObjectItem(params, AWPARA_KEY_DEACTIVEHUMI);
            if(item)
            {
                if(cJSON_IsNumber(item))
                {
                    rt_kprintf(AWPARA_KEY_DEACTIVEHUMI":%d\r\n", item->valueint);
                    para_tmp.deact_humi = item->valueint;
                }
                else
                {
                    rt_kprintf(AWPARA_KEY_DEACTIVEHUMI" not found!\r\n");
                }
            }
            cJSON_Delete(root);
            if(para)
            {
                rt_memcpy(para, &para_tmp, sizeof(para_tmp));
            }
            return 1;
        }
    }
    return 0;
}
/**
 * @brief awparam to str
 * 
 * @param buf 
 * @param buf_len 
 * @param para 
 * @return int >0:pack ok, 0:pack failed.
 */
static int mqtt_property_set_pack(char *buf, int buf_len, int16_t *curhumi, int16_t *curvol, struct awparam *para)
{
    if(buf && para)
    {
        int off = 0;
        off = snprintf(buf+off, buf_len-off, "{\"params\":{");
        if(curhumi)
        {
            int16_t tmp = *curhumi;
            if(tmp < 0)
            {
                tmp = 0;
            }
            off += snprintf(buf+off, buf_len-off, "\""AWPARA_KEY_CURHUMI"\":%d.%d,", tmp/10, tmp%10);
        }
        if(curvol)
        {
            int16_t tmp = *curvol;
            if(tmp < 0)
            {
                tmp = 0;
            }
            off += snprintf(buf+off, buf_len-off, "\""AWPARA_KEY_CURVOL"\":%d,", tmp);
        }
        off += snprintf(buf+off, buf_len-off, 
            "\"IrrigationPumpStatus\":%d,"
            "\""AWPARA_KEY_HUMI100ADC"\":%d,\""AWPARA_KEY_HUMI0ADC"\":%d,"
            "\""AWPARA_KEY_DEACTIVEHUMI"\":%d,\""AWPARA_KEY_ACTIVEHUMI"\":%d,"
            "\""AWPARA_KEY_INTERVALACTIVE"\":%d,\""AWPARA_KEY_INTERVAL"\":%d,\""AWPARA_KEY_HOLDTIME"\":%d}}", 
            pump_active, 
            para->adc100, para->adc0,
            para->deact_humi, para->act_humi,
            para->intvwork,para->interval,para->holdtime);
        if(off > 0)
        {
            return off;
        }
    }
    return 0;
}
static int awparam_save(struct awparam *param);
static void mqtt_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
    iotx_mqtt_topic_info_t *topic_info = (iotx_mqtt_topic_info_pt) msg->msg;

    switch (msg->event_type) {
        case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
            /* print topic name and topic message */
            rt_kprintf("Message Arrived (plen=%d):\r\n", topic_info->payload_len);
            rt_kprintf("Topic  : %.*s\r\n", topic_info->topic_len, topic_info->ptopic);
            rt_kprintf("Payload: %.*s\r\n", topic_info->payload_len, topic_info->payload);
            rt_kprintf("\r\n");
            if(rt_strstr(topic_info->ptopic, "property/set"))
            {
                //
                struct awparam para;
                if(mqtt_property_set_parse(topic_info->payload, &para))
                {
                    if(para.adc0 != -1)
                    {
                        _awparam.adc0 = para.adc0;
                    }
                    if(para.adc100 != -1)
                    {
                        _awparam.adc100 = para.adc100;
                    }
                    if(para.holdtime != -1)
                    {
                        _awparam.holdtime = para.holdtime;
                    }
                    if(para.interval != -1)
                    {
                        _awparam.interval = para.interval;
                    }
                    if(para.intvwork != -1)
                    {
                        _awparam.intvwork = para.intvwork;
                    }
                    awparam_save(&_awparam);
                    //
                    if(pcontext)
                    {
                        rt_event_send(pcontext, AWEVT_HUMI_RESTART);
                    }
                }
            }
            break;
        default:
            break;
    }
}
static void mqtt_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
    rt_kprintf("msg->event_type : %d\r\n", msg->event_type);
}
static const char *sub_topic_list[] =
{
    "/%s/%s/user/get",
    "/sys/%s/%s/thing/service/property/set",
};
static int mqtt_topic_subscribe(void *handle, void *para)
{
    int res = 0;
    char topic[128];
    int topic_len = 0;

    for(int i = 0; i < sizeof(sub_topic_list)/sizeof(sub_topic_list[0]); i++)
    {
        topic_len = strlen(sub_topic_list[i]) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
        if(topic_len > sizeof(topic))
        {
            rt_kprintf("topic buffer is too small! %d\r\n", i);
            continue;
        }
        memset(topic, 0, topic_len);
        rt_snprintf(topic, topic_len, sub_topic_list[i], DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
        res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, mqtt_message_arrive, para);
        if(res < 0)
        {
            rt_kprintf("subscribe failed.%d\r\n", res);
        }
    }
    return res;
}
static int mqtt_topic_unsubscribe(void *handle)
{
    int res = 0;
    char topic[128];
    int topic_len = 0;

    for(int i = 0; i < sizeof(sub_topic_list)/sizeof(sub_topic_list[0]); i++)
    {

        topic_len = strlen(sub_topic_list[i]) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
        if(topic_len > sizeof(topic))
        {
            rt_kprintf("topic buffer is too small! %d\r\n", i);
            continue;
        }
        memset(topic, 0, topic_len);
        rt_snprintf(topic, topic_len, sub_topic_list[i], DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
        res = IOT_MQTT_Unsubscribe(handle, topic);
        if(res < 0)
        {
            rt_kprintf("unsubscribe failed.%d\r\n", res);
        }
    }
    return res;
}

static void *autowater_mqtt_init(void *para)
{
    iotx_mqtt_param_t mqtt_params;
    memset(&mqtt_params, 0x0, sizeof(iotx_mqtt_param_t));
    mqtt_params.handle_event.h_fp = mqtt_event_handle;

    void *pclient = IOT_MQTT_Construct(&mqtt_params);
    if (NULL == pclient) {
        rt_kprintf("MQTT construct failed\r\n");
        return NULL;
    }
    if(mqtt_topic_subscribe(pclient, para) < 0)
    {
        IOT_MQTT_Destroy(&pclient);
        return NULL;
    }
    return pclient;
}
static void autowater_mqtt_deinit(void *handle)
{
    if (NULL == handle)
    {
        return ;
    }
    if(mqtt_topic_unsubscribe(handle) < 0)
    {
        return ;
    }
    IOT_MQTT_Destroy(&handle);
    return ;
}
static int autowater_mqtt_pub(void *data, int size)
{
    const char *fmt = "/sys/%s/%s/thing/event/property/post";
    char topic[128];
    int res;
    rt_snprintf(topic, sizeof(topic), fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
    res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, data, size);
    if(res < 0)
    {
        rt_kprintf("publish failed.%d\r\n", res);
    }
    return res;
}

#define AWATER_HUMI_ADC_CHANNEL     0
/**
 * @brief 
 * 
 * @param vol 
 * @param para 
 * @return int16_t -1=invalid voltage, others=0~1000
 */
static int16_t _vol2humi(int16_t vol, struct awparam *para)
{
    if(para == NULL)
    {
        return -1;
    }
    int16_t p1 = para->adc0 - vol;
    int16_t p2 = para->adc0 - para->adc100;
    if((p1 < 0) || (p1 > p2))
    {
        return -1;
    }
    return (p1*1000u/p2);
}
/**
 * @brief 
 * 
 * @param humi 
 * @param para 
 * @return int -1=deactive, 1=active, 0=no change
 */
static int _pump_active(int16_t humi, int pump_sta, struct awparam *para)
{
    if(pump_sta)
    {
        if(humi > para->deact_humi)
        {
            return -1;
        }
        else
        {
            return 1;
        }
    }
    else
    {
        if(humi < para->act_humi)
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
    return 0;
}
static void autowater_adc_thread_entry(void *param)
{
    uint32_t curevt;
    rt_adc_device_t adc_device = RT_NULL;
    rt_err_t err;
    rt_int16_t vol, humi;
    // ADC初始化
    adc_device = (rt_adc_device_t)rt_device_find("adc0");
    RT_ASSERT(adc_device);
    err = rt_adc_enable(adc_device, 0);
    while(1)
    {
        if(RT_EOK == rt_event_recv(param, AWEVT_HUMI_CHECK, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &curevt))
        {
            vol = 0;
            for(int i=0; i<10; i++)
            {
                vol += rt_adc_voltage(adc_device, 0);
            }
            vol /= 10;
            currentVoltage = vol;
            rt_kprintf("vol:%d.%0.3dV\r\n", vol/1000, vol%1000);
            rt_event_send(param, AWEVT_HUMI_READY);
        }
    }
}

/**
 * @brief load auto water parameters.
 * 
 * @param param 
 * @return bool 0=fail, 1=success
 */
static char para_buf[512];
static void awparam_print(struct awparam *param)
{
    if(param == NULL)
    {
        return ;
    }
    int size = mqtt_property_set_pack(para_buf, sizeof(para_buf), NULL, NULL, param);
    rt_kprintf("%s\r\n", para_buf);
}
static void awparam_set_default(struct awparam *param)
{
    if(param == NULL)
    {
        return ;
    }
    param->interval = 60;
    param->intvwork = 10;
    param->holdtime  = 5;
    param->adc0      = 60;
    param->adc100    = 160;
    param->act_humi  = 750;
    param->deact_humi = 900;
}
static int awparam_load(struct awparam *param)
{
    if(param == NULL)
    {
        return 0;
    }
    while(1)
    {
        int fd = open("/aw.cfg", O_RDWR|O_CREAT);
        if(fd < 0)
        {
            rt_kprintf("open error! %d\r\n", fd);
            rt_thread_delay(RT_TICK_PER_SECOND);
            continue;
        }
        int len = read(fd, para_buf, sizeof(para_buf));
        if(len < 0)
        {
            close(fd);
            rt_kprintf("read error! %d\r\n", len);
            rt_thread_delay(RT_TICK_PER_SECOND);
            continue;
        }
        close(fd);
        para_buf[len] = '\0';
        rt_kprintf("buf:%s\r\n", para_buf);
        struct awparam para;
        if(mqtt_property_set_parse(para_buf, &para))
        {
            rt_memcpy(param, &para, sizeof(struct awparam));
        }
        else
        {
            awparam_set_default(param);
            int size = mqtt_property_set_pack(para_buf, sizeof(para_buf), NULL, NULL, param);
            if(size > 0)
            {
                para_buf[size] = '\0';
                rt_kprintf("para:%s\r\n", para_buf);
                fd = open("/aw.cfg", O_RDWR|O_CREAT|O_TRUNC);
                if(fd >= 0)
                {
                    write(fd, para_buf, size);
                    close(fd);
                }
            }
        }
        break;
    }
    return 1;
}
static int awparam_save(struct awparam *param)
{
    if(param == NULL)
    {
        return 0;
    }
    int fd = open("/aw.cfg", O_RDWR|O_CREAT|O_TRUNC);
    if(fd < 0)
    {
        rt_kprintf("open error! %d\r\n", fd);
        return 0;
    }
    int size = mqtt_property_set_pack(para_buf, sizeof(para_buf), NULL, NULL, param);
    rt_kprintf("buf:%s\r\n", para_buf);
    write(fd, para_buf, size);
    close(fd);
    return 1;
}
static void autowater_timer_entry(void *param)
{
    // rt_kprintf("timer entry!\r\n");
    if(param)
    {
        rt_event_send(param, AWEVT_HUMI_CHECK);
    }
}
static void autowater_pump_timer_entry(void *param)
{
    // rt_kprintf("timer entry!\r\n");
    if(param)
    {
        rt_event_send(param, AWEVT_PUMP_STOP);
    }
}
/**
 * @brief 入口函数
 * @details
 *      1. 初始化ADC，ADC线程
 *      2. 初始化水泵控制引脚，当前线程
 *      3. 初始化阿里云MQTT，连接阿里云，当前线程
 *      4. 创建消息队列，用于线程通讯，当前线程
 *      5. 创建一个定时器，用于定时触发湿度检测
 *      6. 主循环
 *          6.1 等待湿度采集，ADC线程
 *          6.2 判断湿度，根据参数和湿度控制水泵工作，当前线程
 *          6.3 上报湿度、水泵状态至阿里云，当前线程
 */
static char pub_buf[512];
static void autowater_main_thread_entry(void *param)
{
    void *mqttclient = NULL;
    uint32_t curevt;
    rt_event_t evtid = NULL;
    rt_timer_t awadc = NULL;
    rt_timer_t awadcs = NULL;
    rt_thread_t awadc_tid = NULL;
    int16_t curhumi;
    int16_t curvol;
    rt_err_t err;
    // 加载参数
    awparam_load(&_awparam);
    awparam_print(&_awparam);
    // 创建事件组
    evtid = rt_event_create("awevt", RT_IPC_FLAG_FIFO);
    if(evtid == NULL)
    {
        rt_kprintf("create autowater event failed!\r\n");
        goto _exit;
    }
    // 湿度检测线程
    awadc_tid = rt_thread_create("awadc", autowater_adc_thread_entry, evtid, 1024, 10, 20);
    if(awadc_tid)
    {
        rt_thread_startup(awadc_tid);
    }
    else
    {
        rt_kprintf("create autowater adc thread failed!\r\n");
        goto _exit;
    }
    // 初始化水泵控制引脚
    rt_pin_mode(PUMP_PIN,  PIN_MODE_OUTPUT);
    PUMP_NON_ACTIVE(PUMP_PIN);
    // 创建定时器
    awadc = rt_timer_create(
        "awadc", 
        autowater_timer_entry, evtid, 
        RT_TICK_PER_SECOND*_MIN(_awparam.interval, 5), 
        RT_TIMER_FLAG_ONE_SHOT);
    if(awadc == NULL)
    {
        rt_kprintf("create autowater adc timer failed!\r\n");
        goto _exit;
    }
    awadcs = rt_timer_create(
        "awadcs", 
        autowater_pump_timer_entry, evtid, 
        RT_TICK_PER_SECOND*_awparam.holdtime, 
        RT_TIMER_FLAG_ONE_SHOT);
    if(awadc == NULL)
    {
        rt_kprintf("create autowater adc timer failed!\r\n");
        goto _exit;
    }
    pump_active = 0;
    curhumi = 0;
    while(1)
    {
        if(mqttclient)
        {
            if(RT_EOK == rt_event_recv(
                            evtid, 
                            AWEVT_MAIN_BITS, 
                            RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR, 
                            0, &curevt))
            {
                // 水泵控制
                if(curevt & AWEVT_HUMI_READY)
                {
                    int16_t humi;
                    int pump_sta;
                    rt_tick_t tick;
                    curvol = currentVoltage;
                    humi = _vol2humi(curvol, &_awparam);
                    if(humi == -1)
                    {
                        pump_sta = -1;
                        rt_kprintf("invalid humi!\r\n");
                    }
                    else
                    {
                        pump_sta = _pump_active(humi, pump_active, &_awparam);
                        curhumi = humi;
                    }
                    if(pump_sta == 1)
                    {
                        pump_active = 1;
                        PUMP_ACTIVE(PUMP_PIN);
                        tick = _awparam.intvwork*RT_TICK_PER_SECOND;
                        err = rt_timer_control(awadc, RT_TIMER_CTRL_SET_TIME, &tick);
                        if(err != RT_EOK)
                        {
                            rt_kprintf("awadcs set new timeout failed! %d:%d\r\n", err, __LINE__);
                        }
                        err = rt_timer_start(awadcs);
                        if(err != RT_EOK)
                        {
                            rt_kprintf("awadcs start timer failed! %d:%d\r\n", err, __LINE__);
                        }
                    }
                    else if(pump_sta == -1)
                    {
                        pump_active = 0;
                        PUMP_NON_ACTIVE(PUMP_PIN);
                        tick = _awparam.interval*RT_TICK_PER_SECOND;
                        err = rt_timer_control(awadc, RT_TIMER_CTRL_SET_TIME, &tick);
                        if(err != RT_EOK)
                        {
                            rt_kprintf("awadc set new timeout failed! %d:%d\r\n", err, __LINE__);
                        }
                        err = rt_timer_start(awadc);
                        if(err != RT_EOK)
                        {
                            rt_kprintf("awadc start timer failed! %d:%d\r\n", err, __LINE__);
                        }
                    }
                }
                if(curevt & AWEVT_PUMP_STOP)
                {
                    PUMP_NON_ACTIVE(PUMP_PIN);
                    err = rt_timer_start(awadc);
                    if(err != RT_EOK)
                    {
                        rt_kprintf("awadc start timer failed! %d:%d\r\n", err, __LINE__);
                    }
                }
                // MQTT 上报
                {
                    int size = mqtt_property_set_pack(pub_buf, sizeof(pub_buf), &curhumi, &curvol, &_awparam);
                    if(size <= 0)
                    {
                        rt_kprintf("mqtt pack failed!\r\n");
                        continue;
                    }
                    if(autowater_mqtt_pub(pub_buf, size) < 0)
                    {
                        autowater_mqtt_deinit(&mqttclient);
                        rt_thread_delay(RT_TICK_PER_SECOND);
                        mqttclient = autowater_mqtt_init(evtid);
                        if(mqttclient == NULL)
                        {
                            rt_kprintf("reinit autowater mqtt failed!\r\n");
                            goto _exit;
                        }
                    }
                }
                if(curevt & AWEVT_HUMI_RESTART)
                {
                    rt_tick_t tick;
                    rt_timer_stop(awadc);
                    if(pump_active)
                    {
                        tick = RT_TICK_PER_SECOND*_awparam.intvwork;
                    }
                    else
                    {
                        tick = RT_TICK_PER_SECOND*_awparam.interval;
                    }
                    err = rt_timer_control(awadc, RT_TIMER_CTRL_SET_TIME, &tick);
                    if(err != RT_EOK)
                    {
                        rt_kprintf("awadc set new timeout failed! %d:%d\r\n", err, __LINE__);
                    }
                    err = rt_timer_start(awadc);
                    if(err != RT_EOK)
                    {
                        rt_kprintf("awadc start timer failed! %d:%d\r\n", err, __LINE__);
                    }
                }
            }
            IOT_MQTT_Yield(NULL, 100);
        }
        else
        {
            // 水泵停止
            PUMP_NON_ACTIVE(PUMP_PIN);
            // 停止定时器
            if(awadcs)
            {
                rt_timer_stop(awadcs);
            }
            else
            {
                // 定时器异常
                break;
            }
            if(awadc)
            {
                rt_timer_stop(awadc);
            }
            else
            {
                // 定时器异常
                break;
            }
            // 网络检查
            if(_net_stat_check())
            {
                // 网络准备好
                rt_kprintf("try to create mqtt client.\r\n");
                // mqtt客户端创建
                mqttclient = autowater_mqtt_init(evtid);
                if(mqttclient)
                {
                    // 启动定时器
                    rt_timer_start(awadc);
                }
            }
            else
            {
                rt_kprintf("network not ready!\r\n");
            }
            if(mqttclient == NULL)
            {
                rt_thread_delay(RT_TICK_PER_SECOND*2);
            }
        }
    }
_exit:
    if(awadc_tid)
    {
        rt_thread_delete(awadc_tid);
        awadc_tid = NULL;
    }
    if(awadcs)
    {
        rt_timer_stop(awadcs);
        rt_timer_delete(awadcs);
    }
    if(awadc)
    {
        rt_timer_stop(awadc);
        rt_timer_delete(awadc);
    }
    if(mqttclient)
    {
        IOT_MQTT_Destroy(&mqttclient);
    }
    if(evtid)
    {
        rt_event_delete(evtid);
    }
}

int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1]);
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
static int autowater_init(void)
{
    HAL_GetProductKey(DEMO_PRODUCT_KEY);
    HAL_GetDeviceName(DEMO_DEVICE_NAME);
    HAL_GetDeviceSecret(DEMO_DEVICE_SECRET);

    rt_kprintf("key:%s, dev_name:%s, dev_sect:%s\r\n",
        DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME, DEMO_DEVICE_SECRET);
    
    rt_thread_t autowater_proxy = rt_thread_create("awmain", autowater_main_thread_entry, NULL, 8192, 10, 20);
    if(autowater_proxy)
    {
        rt_thread_startup(autowater_proxy);
    }
    else
    {
        rt_kprintf("create autowater proxy thread failed!\r\n");
    }
    return 0;
}
//INIT_APP_EXPORT(autowater_init);
